package mesh

import (
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type MeshRepository interface {
	base.Repository

	FindMeshBy_id(id primitive.ObjectID) (*Model, error)
	FindMeshByUrl(url string) (*Model, error)
	FindMany(filter bson.M) ([]*Model, error)
}

func NewMeshRepository() MeshRepository {
	return &meshRepository{
		RepositoryStruct: base.RepositoryStruct{
			CollectionName: server.MeshCollectionName,
		},
	}
}

// visual
type meshRepository struct {
	base.RepositoryStruct
}

func (m *meshRepository) Insert(mdl *model.DataUserModel) error {
	mesh, ok := mdl.Data.(*Model)
	if !ok {
		return errors.New("mesh type error")
	}

	if err := m.CheckDB(); err != nil {
		return err
	}

	mesh.ResolveEntity(mesh, mdl.User)

	_, err := m.Mongo.InsertOne(m.CollectionName, *mesh)
	return err
}

func (m *meshRepository) FindMeshBy_id(id primitive.ObjectID) (*Model, error) {
	filter := bson.M{"_id": id}
	return m.find(filter)
}

func (m *meshRepository) FindMeshByUrl(url string) (*Model, error) {
	filter := bson.M{"Url": url}
	return m.find(filter)
}

func (m *meshRepository) find(filter bson.M) (*Model, error) {
	db, err := server.Mongo()
	if err != nil {
		return nil, err
	}
	var result Model
	find, err := db.FindOne(server.MeshCollectionName, filter, &result)
	if err != nil {
		return nil, err
	}
	if find {
		return &result, nil
	}
	return nil, nil
}

func (m *meshRepository) FindMany(filter bson.M) ([]*Model, error) {
	if err := m.CheckDB(); err != nil {
		return nil, err
	}

	var res []*Model
	err := m.Mongo.FindMany(m.CollectionName, filter, &res)
	if err != nil {
		return nil, err
	}

	return res, nil
}
